package main

import (
	"fmt"
	example "goim-pro/api/protos/example"
	protos "goim-pro/api/protos/salty"
	"goim-pro/pkg/utils"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/reflection"
	"log"
	"net"
)

const (
	address = "127.0.0.1:8080"
)

type server struct{}

func (server) SayHello(ctx context.Context, req *example.HelloReq) (resp *example.HelloResp, err error) {
	name := req.Name
	message := fmt.Sprintf("Hello %s, wellcome!!!", name)
	fmt.Println(message)

	resp = &example.HelloResp{
		Message: message,
	}
	return
}

func main() {
	lis, err := net.Listen("tcp", address)
	if err != nil {
		log.Fatalf("监听失败: %v", err)
	} else {
		log.Printf("开始监听...")
	}

	var opts []grpc.ServerOption

	var interceptor grpc.UnaryServerInterceptor
	interceptor = func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
		fmt.Println(info.FullMethod)

		var in = req.(*protos.GrpcReq)

		var acReq example.HelloReq
		if err := utils.UnMarshalAnyToMessage(in.Data, &acReq); err != nil {
			fmt.Println(err)
			return nil, err
		}

		return handler(ctx, &acReq)
	}

	opts = append(opts, grpc.UnaryInterceptor(interceptor))

	s := grpc.NewServer(opts...) // 创建 gRPC 服务

	// 注册接口服务
	//example.RegisterWaiterServer(s, &server{})

	s.RegisterService(&Waiter_serviceDesc, &server{})

	// 在 gRPC 服务器上注册反射服务
	reflection.Register(s)

	// 将监听交给 gRPC 服务处理
	err = s.Serve(lis)
	if err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

func Waiter_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(protos.GrpcReq)
	if err := dec(in); err != nil {
		return nil, err
	}
	var acReq example.HelloReq
	if err := utils.UnMarshalAnyToMessage(in.Data, &acReq); err != nil {
		fmt.Println(err)
		return nil, err
	}

	if interceptor == nil {
		return srv.(example.WaiterServer).SayHello(ctx, &acReq)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/com.salty.protos.Waiter/SayHello",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(example.WaiterServer).SayHello(ctx, req.(*example.HelloReq))
	}
	return interceptor(ctx, in, info, handler)
}

var Waiter_serviceDesc = grpc.ServiceDesc{
	ServiceName: "com.salty.protos.Waiter",
	HandlerType: (*example.WaiterServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "SayHello",
			Handler:    Waiter_SayHello_Handler,
		},
	},
	Streams:  []grpc.StreamDesc{},
	Metadata: "hello.proto",
}

